/* eslint-disable no-prototype-builtins */
/* eslint-disable no-redeclare */
import axios from 'axios'
import { Message, Loading } from 'element-ui'
import router from '@/router/index.js'
import NProgress from 'nprogress'
import { getTokenM } from './getToken.js'
// loading
let loadFlag = true
let loadingInstance = null
let isPrompting = false // 是否正在提示
/* -----------------登录 begin----------------- */
const httpForm = axios.create({
  withCredentials: true, // true允许跨域，false不允许跨域
  timeout: 600000, // 超时40秒
  headers: {
    'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8',
    Authorization: 'Basic b21zOm9tc19zZWNyZXQ=' // 这里请求登录时需要修改
  },
  transformRequest: [
    function(data) {
      let newData = ''
      for (const k in data) {
        if (data.hasOwnProperty(k) === true) {
          newData += encodeURIComponent(k) + '=' + encodeURIComponent(data[k]) + '&'
        }
      }
      return newData
    }
  ]
})
// 请求拦截器
httpForm.interceptors.request.use(
  config => {
    startLoading()
    return config
  },
  err => {
    console.log(err)
    return Promise.reject(err)
  }
)

// 响应拦截器
httpForm.interceptors.response.use(
  res => {
    endLoading()
    return res
  },
  error => {
    endLoading()
    // 错误的请求处理，这里根据后台返回的状态吗返回相应的信息
    if (error.response.status == 401 || error.response.status == 403) {
      Message({
        message: error.response.data.message,
        type: 'error'
      })
    }
  }
)
function apiAuthorization(method, url, params, response) {
  const requetParam = {
    method: method,
    url: url,
    data: method === 'POST' || method === 'PUT' ? params : null,
    params: method === 'GET' || method === 'DELETE' ? params : null
  }
  httpForm(requetParam)
    .then(function(res) {
      response(res.data)
    })
    .catch(function(err) {
      response(err)
    })
}
/* -----------------登录----------------- end */
const http = axios.create({
  baseURL: getTokenM('baseURL'),
  timeout: 600000, // 超时40秒
  headers: {
    Authorization: getTokenM(),
    'Content-Type': 'application/json;charset=utf-8'
  },
  withCredentials: true, // true允许跨域，false不允许跨域
  transformRequest: [
    function(data) {
      if (Object.prototype.toString.call(data) === '[object Array]') {
        var newData = []
      } else if (Object.prototype.toString.call(data) === '[object Object]') {
        var newData = {}
      }
      for (const k in data) {
        if (data.hasOwnProperty(k) === true) {
          newData[encodeURIComponent(k)] = data[k]
        }
      }
      if (newData == undefined) {
        return data
      } else {
        return JSON.stringify(newData)
      }
    }
  ]
})
// 请求拦截器
http.interceptors.request.use(
  config => {
    !config.unloading && startLoading()
    return config
  },
  err => {
    console.log(err)
    return Promise.reject(err)
  }
)

// 响应拦截器
http.interceptors.response.use(
  res => {
    endLoading()
    if (res.data.code == '10027') {
      Message({
        type: 'error',
        message: res.data.message,
        duration: 1500,
        onClose: () => {
          return res.data
        }
      })
    } else {
      return res.data
    }
  },
  error => {
    endLoading()
    if (error.response.status == 401) {
      if (!isPrompting) {
        isPrompting = true
        Message({
          type: 'error',
          message: '登录验证失败，请重新登录',
          duration: 1500,
          onClose: () => {
            isPrompting = false
            router.push('/login')
          }
        })
      }
    } else if (error.response.status == 500 || error.response.status == 502) {
      if (!isPrompting) {
        isPrompting = true
        Message({
          type: 'error',
          message: '网络错误，请稍后再试',
          onClose: () => {
            isPrompting = false
          }
        })
      }
      return
    } else if (error.response.status == 404) {
      if (!isPrompting) {
        isPrompting = true
        Message({
          message: '没有找到对应接口。404',
          type: 'error',
          duration: 1500,
          onClose: () => {
            isPrompting = false
          }
        })
      }
    } else {
      Message({
        message: error.response.message,
        type: 'error',
        duration: 1500
      })
    }
    return error.response.data
  }
)

/* 上传类型控制  begin*/
function apiAxios(method, url, params, response) {
  // 获取token
  accessToken()
  let requetParam = {
    method: method,
    url: url,
    headers: {
      'Content-Type': 'application/json;charset=utf-8'
    },
    // responseType: 'JSON', // 返回的不是JSON数据格式，会出警告
    data: method === 'POST' || method === 'PUT' ? params : null,
    params: method === 'GET' || method === 'DELETE' ? params : null
  }
  if (method == 'arraybuffer') {
    requetParam = {
      method: 'POST',
      url: url,
      responseType: 'arraybuffer',
      headers: {
        'Content-Type': 'application/json;charset=utf-8'
      },
      data: null,
      params: null
    }
  } else if (method == 'file') {
    // 这种上传图片不兼容iphone
    requetParam = {
      method: 'POST',
      url: url,
      headers: {
        'Content-Type': 'multipart/form-data'
      },
      data: params
    }
  } else if (method == 'blob') {
    // 下载excel
    requetParam = {
      method: 'POST',
      url: url,
      responseType: 'blob',
      headers: {
        'Content-Type': 'application/json;charset=UTF-8'
        // 'Content-Type': 'application/vnd.ms-excel;charset=UTF-8',
      },
      data: params,
      params: null
    }
  } else if (method == 'blobzip') {
    // 下载zip
    requetParam = {
      method: 'GET',
      url: url,
      responseType: 'blob',
      headers: {
        'Content-Type': 'application/octet-stream'
      },
      data: params,
      params: null
    }
  } else if (method === 'DELETE') {
    requetParam = {
      method: 'delete',
      url: url,
      headers: {
        'Content-Type': 'application/json;'
      },
      data: params,
      params: null
    }
  }
  http(requetParam)
    .then(function(res) {
      response(res)
    })
    .catch(function(err) {
      response(err)
    })
}
/* 上传类型控制 end */
/* 拦截器设置token begin */
function accessToken() {
  return http.interceptors.request.use(
    config => {
      config.headers.Authorization = getTokenM()
      return config
    },
    error => {
      return Promise.reject(error)
    }
  )
}
/* 拦截器设置token end */
function axiosRes(url, params, response) {
  // 上传图片 兼容iphone
  startLoading()
  axios
    .request({
      url: url,
      method: 'post',
      data: params,
      headers: {
        Authorization: getTokenM()
      }
    })
    .then(function(res) {
      endLoading()
      response(res)
    })
    .catch(function(err) {
      endLoading()
      response(err)
    })
}
/* -----------------loading----------------- begin*/
function startLoading() {
  NProgress.start()
  if (loadingInstance === null) {
    loadingInstance = Loading.service({
      target: '.el-main',
      text: '拼命加载中...',
      background: 'rgba(255, 255, 255, 0.5)'
    })
  }
  loadFlag = false
}

function endLoading() {
  if (loadFlag !== true) {
    NProgress.done()
    loadFlag = true
  }
  if (loadingInstance != null) {
    loadingInstance.close()
  }
  loadingInstance = null
}
/* -----------------loading----------------- end*/

/**
 * 去除全局nprogress请求
 */
const instance = axios.create({
  baseURL: getTokenM('baseURL'),
  timeout: 600000, // 超时40秒
  headers: {
    Authorization: getTokenM(),
    'Content-Type': 'application/json;charset=utf-8'
  },
  withCredentials: true, // true允许跨域，false不允许跨域
  transformRequest: [
    function(data) {
      if (Object.prototype.toString.call(data) === '[object Array]') {
        var newData = []
      } else if (Object.prototype.toString.call(data) === '[object Object]') {
        var newData = {}
      }
      for (const k in data) {
        if (data.hasOwnProperty(k) === true) {
          newData[encodeURIComponent(k)] = data[k]
        }
      }
      if (newData == undefined) {
        return data
      } else {
        return JSON.stringify(newData)
      }
    }
  ]
})

instance.interceptors.request.use(
  config => {
    return config
  },
  err => {
    console.log(err)
    return Promise.reject(err)
  }
)
instance.interceptors.response.use(
  res => {
    if (res.data.code == '10027') {
      Message({
        type: 'error',
        message: res.data.message,
        duration: 1500,
        onClose: () => {
          return res.data
        }
      })
    } else {
      return res.data
    }
  },
  error => {
    if (error.response.status == 401) {
      if (!isPrompting) {
        isPrompting = true
        Message({
          type: 'error',
          message: '登录验证失败，请重新登录',
          duration: 1500,
          onClose: () => {
            isPrompting = false
            router.push('/login')
          }
        })
      }
    } else if (error.response.status == 500 || error.response.status == 502) {
      if (!isPrompting) {
        isPrompting = true
        Message({
          type: 'error',
          message: '网络错误，请稍后再试',
          onClose: () => {
            isPrompting = false
          }
        })
      }
      return
    } else if (error.response.status == 404) {
      if (!isPrompting) {
        isPrompting = true
        Message({
          message: '没有找到对应接口。404',
          type: 'error',
          duration: 1500,
          onClose: () => {
            isPrompting = false
          }
        })
      }
    } else {
      Message({
        message: error.response.message,
        type: 'error',
        duration: 1500
      })
    }
    return error.response.data
  }
)
export { instance }

export default {
  request: http,
  get: function(url, params, response) {
    return apiAxios('GET', url, params, response)
  },
  post: function(url, params, response) {
    return apiAxios('POST', url, params, response)
  },
  put: function(url, params, response) {
    return apiAxios('PUT', url, params, response)
  },
  delete: function(url, params, response) {
    return apiAxios('DELETE', url, params, response)
  },
  arraybuffer: function(url, params, response) {
    return apiAxios('arraybuffer', url, params, response)
  },
  blob: function(url, params, response) {
    return apiAxios('blob', url, params, response)
  },
  blobzip: function(url, params, response) {
    return apiAxios('blobzip', url, params, response)
  },
  file: function(url, params, response) {
    return axiosRes(url, params, response)
  },
  postEncryption: function(url, params, response) {
    return apiAuthorization('POST', url, params, response)
  }
}
